"""
-*- coding:utf-8 -*-
@Time:2025/6/11 14:30
@Author: viawang
@Email:  939654454@qq.com
@Wechat:bluesky___9999
@File:like_comment.py
"""

import random
import subprocess
import time
import traceback

from commonmethods import CommonMethods
from hot_tools.xinghuo_tools import XinghuoTools
from loguru import logger


# TODO 抖音点赞评论功能

class LikeComment(CommonMethods, XinghuoTools):
    def __init__(self, executable_path,profile_id, debugger_port, phone_number, unifiedprompt, xinghuodata):
        CommonMethods.__init__(self, executable_path, profile_id, debugger_port)
        XinghuoTools.__init__(self)
        self.phone_number = phone_number
        self.is_logged_in = False
        self.unifiedprompt = unifiedprompt
        self.xinghuocookies, self.xinghuofd, self.xinghuochatId = xinghuodata
        self.likecomimg_dir = r"imgs/likecomment_imgs"
        self.screenshotpic = fr"{self.likecomimg_dir}/screenshot_{profile_id}.jpg"
        self.activenolive_ele = '[data-e2e="feed-active-video"] video[playsinline][autoplay]'  # 当前活跃的非直播视频元素
        self.activelive_ele = '[data-e2e="feed-live"] .DW9kK9Ef'  # 当前活跃的直播视频元素
        self.activelivetitle_ele = '[data-e2e="feed-live"] .LKe3EDLc'  # 当前活跃的直播视频标题元素
        self.active_nonlivetitle_ele = '[data-e2e="feed-active-video"] .arnSiSbK.hT34TYMB.ONzzdL2F'  # 当前活跃的非直播视频标题元素
        self.commentinput_ele = '[data-e2e="feed-active-video"] .GXmFLge7'  # 当前活跃的非直播视频评论输入框元素
        self.commentfold_ele = '[data-e2e="feed-active-video"] .cG83852M'  # 当前活跃的非直播视频评论折叠栏元素
        self.commentcolumn_ele = '[data-e2e="feed-active-video"] #semiTabcomment'  # 当前活跃的非直播视频评论栏元素
        self.commenteidt_ele = '[data-e2e="feed-active-video"] [contenteditable="true"]'  # 当前活跃的非直播视频评论可编辑元素
        self.videoduration_ele = '[data-e2e="feed-active-video"] .time-duration'  # 当前活跃的非直播视频的总时长
        self.videoplayed_ele = '[data-e2e="feed-active-video"] .time-current'  # 当前活跃的非直播视频的已播时长
        self.nextvideo_ele = '[data-e2e="video-switch-next-arrow"]'  # 下一个视频按钮元素
        self.pausevideo_ele = '[data-e2e="feed-active-video"] .xgplayer-start.hide[data-state="play"]'  # 当前视频暂停播放元素
        self.playvideo_ele = '[data-e2e="feed-active-video"] .xgplayer-start.hide[data-state="pause"]'  # 当前视频正在播放元素
        self.secVerinput_ele = 'input[maxlength="6"][placeholder="请输入验证码"]'  # 二次验证码输入框元素

    def doLogin(self):
        """检查和执行登录操作"""
        try:
            # 检查是否已登录
            self.is_logged_in = self.check_login_status()
            if not self.is_logged_in:
                # 未登录，则优先尝试扫码登录
                logger.debug(f"用户《{self.profile_id}》未登录,准备执行扫码登录...")
                qr_login_success = self.wait_for_qr_login()
                # 如果扫码登录失败，执行短信验证码登录流程
                if not qr_login_success:
                    logger.debug(f"用户《{self.profile_id}》扫码登录失败,准备执行短信验证码登录...")
                    sms_login_success = self.wait_for_sms_login()
                    if not sms_login_success:
                        logger.error(f"用户《{self.profile_id}》短信验证码登录失败...")
                    else:
                        logger.success(f"用户《{self.profile_id}》: 短信验证码登录成功...")
                        self.is_logged_in = True
                else:
                    logger.success(f"用户《{self.profile_id}》: 扫码登录成功！")
                    self.is_logged_in = True
            else:
                logger.info(f"用户《{self.profile_id}》已是登录状态了...跳过登录流程")
                self.is_logged_in = True

            return self.is_logged_in

        except Exception as e:
            logger.error(f"登录检查失败: {e}")
            return False

    def check_login_status(self):
        """检查用户是否已登录：通过判断登录按钮是否存在"""
        try:
            login_button = self.page.get_by_role("button", name="登录", exact=True)  # 定位登录按钮 exact=True精确匹配文字
            button_count = login_button.count()  # 用count()判断元素是否存在（0表示不存在，>0表示存在）
            if button_count > 0:
                return False
            else:
                return True

        except Exception as e:
            logger.error(f"用户《{self.profile_id}》检查登录状态失败: {e}")
            return False  # 异常时默认视为未登录

    def wait_for_sms_login(self):
        """执行sms短信登录"""
        try:
            # 输入手机号
            input_phone_ele = self.page.get_by_placeholder("请输入手机号")
            input_phone_ele.wait_for(timeout=5000)  # 等待输入手机号的输入框出现
            input_phone_ele.fill(self.phone_number)
            logger.info(f"已输入手机号...{self.phone_number}")

            # 点击获取验证码
            code_button = self.page.get_by_text("获取验证码")
            code_button.click()

            # 输入短信验证码
            input_code_ele = self.page.get_by_placeholder("请输入验证码")
            input_code_ele.wait_for(timeout=5000)  # 等待输入验证码的输入框出现
            smscode = input("请输入你收到的短信验证码：")
            input_code_ele.fill(smscode)

            # 点击登录/注册按钮
            login_button = self.page.get_by_text("登录/注册", exact=True)
            login_button.click()

        except Exception as e:
            logger.error(f"执行登录失败: {e}")

    def wait_for_qr_login(self, timeout=120):
        """等待用户手动扫码登录成功"""
        logger.info(f"用户《{self.profile_id}》: 请在{timeout}s内在浏览器中完成扫码登录的流程...")
        start_time = time.time()
        check_count = 0
        while time.time() - start_time < timeout:
            # 检查登录状态
            if self.check_login_status():
                return True
            # 每5秒检查一次
            check_count += 1
            self.page.wait_for_timeout(5000)
            # 每30秒提醒一次
            if check_count % 6 == 0:
                elapsed = int(time.time() - start_time)
                remaining = timeout - elapsed
                logger.info(f"用户《{self.profile_id}》: 等待扫码登录中... 已等待{elapsed}秒，剩余{remaining}秒")

        logger.error(f"用户《{self.profile_id}》: 扫码登录超时")
        return False

    def checkifplay(self):
        """检查视频是否在播放中，暂停状态则执行播放"""
        playlocator = self.page.locator(self.playvideo_ele)  # 定位当前暂停播放按钮元素
        pauselocator = self.page.locator(self.pausevideo_ele)  # 定位当前暂停播放按钮元素
        try:
            if pauselocator.count() > 0 and pauselocator.is_visible() and pauselocator.is_enabled():
                logger.warning(f"用户《{self.profile_id}》当前视频处于暂停播放状态，准备点击播放...")
                pauselocator.click()
        except:
            logger.warning(f"checkifplay的try报错....准备检测是否真的在播放...")
            if playlocator.count() > 0 and playlocator.is_enabled():
                logger.warning(f"用户《{self.profile_id}》当前视频已处于播放状态，无需操作")
                return True

    def checkifmute(self, max_wait_time=30):
        """检查当前视频是否为静音，是，则开启声音"""
        nolivemute_svg = self.page.locator('span.semi-icon.semi-icon-default.xg-volume-mute').nth(0)  # 非直播静音键元素
        nolivevolume_svg = self.page.locator('span.semi-icon.semi-icon-default.xg-volume').nth(0)  # 非直播声音键元素
        livemute_svg = self.page.locator('svg.xg-volume-mute').nth(0)  # 直播视频静音键元素
        livevolume_svg = self.page.locator('svg.xg-volume').nth(0)  # 直播视频声音键元素
        starttime = time.time()
        while time.time() - starttime <= max_wait_time:
            if nolivemute_svg.count() > 0 and nolivemute_svg.is_visible() and nolivemute_svg.is_enabled():
                nolivemute_svg.click()
                logger.success(f"非直播视频声音初始状态是静音，用户《{self.profile_id}》已开启声音...")
                return True
            elif nolivevolume_svg.count() > 0 and nolivevolume_svg.is_visible():
                logger.debug(f"用户《{self.profile_id}》非直播视频已经是开启声音的状态了...")
                return True

            elif livemute_svg.count() > 0 and livemute_svg.is_visible() and livemute_svg.is_enabled():
                livemute_svg.click()
                logger.success(f"直播视频声音初始状态是静音，用户《{self.profile_id}》已开启声音...")
                return True

            elif livevolume_svg.count() > 0 and livevolume_svg.is_visible():
                logger.debug(f"用户《{self.profile_id}》直播视频已经是开启声音的状态了...")
                return True
            else:
                if time.time() - starttime > max_wait_time:
                    logger.error(f"checkifmute功能检查失败：{traceback.format_exc()}")

    def checkiflive(self, video_count):
        """检查是否为直播视频"""
        active_live_tag = self.page.locator(self.activelive_ele)  # 定位直播视频元素
        if active_live_tag.count() > 0 and active_live_tag.is_visible() and active_live_tag.is_enabled():
            title_texts = self.page.locator(self.activelivetitle_ele).text_content()  # 获取直播视频标题
            logger.warning(f"用户《{self.profile_id}》检测到第{video_count}个视频是\x1b[31m直播视频\x1b[0m，标题文本信息：{title_texts}，跳过点赞流程...")
            return True
        return False

    def checkifad(self, video_count):
        """检查是否为广告视频"""
        try:
            # 检查常见的广告标识
            ad_indicators = [
                self.page.locator('[data-e2e="feed-active-video"] path[d^="M9.492 2.004L8.22"]'),
                self.page.locator('[data-e2e="feed-active-video"] .DApkB5k0')
            ]
            for indicator in ad_indicators:
                if indicator.count() > 0 and indicator.is_visible() and indicator.is_enabled():
                    title_texts = self.page.locator(self.active_nonlivetitle_ele).text_content()  # 获取广告视频的标题
                    logger.warning(f"用户《{self.profile_id}》检测到第{video_count}个视频是\x1b[31m广告视频\x1b[0m，标题文本信息：{title_texts}，跳过点赞流程...")
                    return True
            return False
        except Exception as e:
            logger.debug(f"用户《{self.profile_id}》广告检查失败: {e}")
            return False

    def checkifliked(self, video_count):
        """检查是否已点赞"""
        likedbtn_locator = '[data-e2e="feed-active-video"] [data-e2e-state="video-player-is-digged"]'
        try:
            # 查找已点赞的按钮状态
            liked_button = self.page.locator(likedbtn_locator)
            if liked_button.count() > 0 and liked_button.is_visible() and liked_button.is_enabled():
                title_texts = self.page.locator(self.active_nonlivetitle_ele).text_content()  # 获取已点赞过的视频标题
                logger.warning(f"用户《{self.profile_id}》检测到第{video_count}个视频是\x1b[31m点赞过的视频\x1b[0m，标题文本信息：{title_texts}，跳过点赞流程...")
                return True
            return False
        except Exception as e:
            logger.debug(f"用户《{self.profile_id}》点赞状态检查失败: {e}")
            return False

    def checkifcommentsect(self):
        """检查评论区是否打开：发表评论输入框定位、评论栏目兜底，进行验证"""
        commentfold_locator = self.page.locator(self.commentfold_ele)
        commentcolumn_locator = self.page.locator(self.commentcolumn_ele)

        if commentfold_locator.count() > 0 and commentfold_locator.is_visible() and commentfold_locator.is_enabled():
            logger.debug(f"用户《{self.profile_id}》检测到评论折叠栏，说明未打开评论区，准备打开中...")
            return False

        elif commentcolumn_locator.count() > 0 and commentcolumn_locator.is_visible():
            logger.debug(f"用户《{self.profile_id}》检测到评论栏，说明已打开评论区...")
            return True
        else:
            logger.warning(f"用户《{self.profile_id}》评论区未打开, 准备打开中...")
            return False

    def getvideoduration(self, max_wait_time=60):
        """获取视频时长"""

        def time_to_seconds(time_str):
            """工具函数：将"分:秒"或"时:分:秒"格式转为秒数"""
            parts = list(map(int, time_str.split(':')))
            if len(parts) == 2:
                # 分:秒格式
                minutes, seconds = parts
                return minutes * 60 + seconds
            elif len(parts) == 3:
                # 时:分:秒格式
                hours, minutes, seconds = parts
                return hours * 3600 + minutes * 60 + seconds
            else:
                raise ValueError(f"不支持的时间格式：{time_str}（需为分:秒或时:分:秒）")

        start_time = time.time()
        check_count = 0
        while time.time() - start_time < max_wait_time:
            check_count += 1
            try:
                total = self.page.locator(self.videoduration_ele).text_content()  # 获取视频总时长
                played = self.page.locator(self.videoplayed_ele).text_content()  # 获取视频已播时长
                if total and total != "00:00":
                    total_sec = time_to_seconds(total)
                    played_sec = time_to_seconds(played)
                    left_sec = max(0, total_sec - played_sec)
                    logger.success(f"用户《{self.profile_id}》已获取到可点赞视频的时长信息：{played}/{total}, 即总时长：{total_sec}s, 已播时长：{played_sec}s, 剩余未播时长：{left_sec}s")
                    return total_sec, played_sec, left_sec
                self.page.wait_for_timeout(random.uniform(500, 1000))
            except Exception as e:
                if time.time() - start_time > max_wait_time:
                    logger.debug(f"用户《{self.profile_id}》第{check_count}次检查失败: {e}")

    def gencomment(self):
        """AI 图文处理"""
        candidates = [
            ("星火 AI", self._call_xinghuo),
        ]
        self.page.screenshot(path=self.screenshotpic)

        for name, handler in candidates:
            try:
                aicomment = handler()
                if aicomment.strip():
                    logger.success(f"用户《{self.profile_id}》调用（{name}）图片理解成功！")
                    return aicomment
            except Exception as e:
                logger.debug(f"用户《{self.profile_id}》{name} 失败：{e}")
        logger.error("所有图片理解方案均失败，返回空字符串")
        return ""

    def _call_xinghuo(self):
        prompt = self.unifiedprompt or self.xinghuoprompt
        return self.xinghuoai_imghandle(self.screenshotpic, prompt,
                                        self.xinghuocookies, self.xinghuofd, self.xinghuochatId)

    def like_video(self, total_seconds, played_seconds, left_seconds):
        """处理点赞视频的时机（带动态倒计时）"""
        if total_seconds >= 60:
            left_seconds = random.randint(10, 60)  # 视频总时长超过60s，则统一定义随机观看时长

        for remaining in range(left_seconds, 0, -1):
            logger.opt(raw=True).info(f"\r用户《{self.profile_id}》剩余观看视频 {remaining:2d} 秒后执行点赞操作...")
            self.page.wait_for_timeout(1000)
        element = self.page.locator(self.activenolive_ele).nth(0)
        bounding_box = element.bounding_box()
        if bounding_box:
            random_x = bounding_box['x'] + random.uniform(100, bounding_box['width'] / 2)
            random_y = bounding_box['y'] + random.uniform(200, bounding_box['height'] / 2)
            self.page.mouse.click(random_x, random_y, button='left', click_count=2)
            logger.success(f"用户《{self.profile_id}》已对该视频完成了点赞操作...")
        else:
            raise Exception(f"用户《{self.profile_id}》未找到可点击的视频区域")

    def comment_video(self, commentcontent):
        """发表视频评论"""
        self.page.locator(self.commentinput_ele).click()
        self.page.locator(self.commenteidt_ele).fill(commentcontent)
        self.page.wait_for_timeout(random.uniform(500, 1000))
        self.page.keyboard.press('Enter')
        logger.success(f"用户《{self.profile_id}》已发表评论...")

    def click_nextvideo(self):
        """点击完下一条视频"""
        next_btn = self.page.locator(self.nextvideo_ele)  # 下一个视频按钮元素
        if next_btn.count() > 0 and next_btn.is_visible() and next_btn.is_enabled():
            next_btn.click()
            logger.success(f"用户《{self.profile_id}》已点击下一个视频按钮...")
            return True
        else:
            logger.error(f"用户《{self.profile_id}》未点击下一个视频的按钮...")
            return False

    def likecomment_business(self, max_videos=100):
        """处理视频流的主要业务逻辑"""
        self.launch()  # 初始化浏览器
        self.doLogin()  # 检查和执行登录操作
        self.checkifplay()  # 检查视频是否正在播放
        self.checkifmute()  # 检查视频声音是否开启
        opencommentsect = self.checkifcommentsect()  # 检查评论区是否打开
        video_count = 1
        while video_count <= max_videos:
            self.page.wait_for_timeout(random.uniform(500, 1000))
            logger.info(f"{'*' * 50}用户《{self.profile_id}》第{video_count}个视频总览信息{'*' * 50}")
            if self.checkiflive(video_count) or self.checkifad(video_count) or self.checkifliked(video_count):  # 检查是否为直播、广告、已点赞过的视频
                self.page.wait_for_timeout(random.randint(500, 1000))
            else:
                if not opencommentsect:
                    self.page.keyboard.press('x')
                    logger.debug(f"用户《{self.profile_id}》已打开评论区...")
                    opencommentsect = True
                title_texts = self.page.locator(self.active_nonlivetitle_ele).text_content()  # 获取当前活跃的可点赞的视频标题
                logger.success(f"用户《{self.profile_id}》检测到第{video_count}个视频是可点赞的视频，标题文本信息：{title_texts}，准备执行点赞流程...")
                total_sec, played_sec, left_sec = self.getvideoduration()  # 获取可点赞视频的视频时长信息
                aicomment = self.gencomment()  # 使用ai生成智能评论
                self.like_video(total_sec, played_sec, left_sec)  # 处理点赞视频时机
                self.comment_video(aicomment)  # 发表视频评论
                self.page.wait_for_timeout(random.uniform(3000, 5000))
            video_count += 1
            self.click_nextvideo()
        logger.success(f"用户《{self.profile_id}》已完成 {max_videos} 个视频的点赞评论业务...")
        self.page.keyboard.press('Space')
